博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
8.6 如何限制未认证用户访问有权限网页
阅读量:4095 次
发布时间:2019-05-25

本文共 3572 字,大约阅读时间需要 11 分钟。

——————————前言——————————————

上节我们讲了注册时向用户发送确认邮件, 确认成功把用户的confirm属性值改为1, 默认为0.

本节我们来利用这个confirm值来做些文章, 让未确认的用户登录以后不能看到主页, 显示一个页面提醒用户未确认账户, 让用户登录邮箱确认账户, 或者是选择重新发送确认邮件。

——————————————————————————

一. 修改|-app/-auth/views.py

@auth.before_app_requestdef before_request():    if current_user.is_authenticated() \  #用户已登录且        and not current_user.confirm \  #用户未认证且        and request.endpoint[:5] != 'auth.' \  #请求端点不为auth蓝本定义的路由        and request.endpoint != 'static':  #请求断点不为static        return redirect(url_for('auth.unconfirmed'))  #重定向@auth.route('/unconfirmed')def unconfirmed():    if current_user.is_anonymous or current_user.confirm:  #防止已用户重复访问该链接        return redirect(url_for('main.index'))    return render_template('auth/unconfirmed.html')  #返回未确认页面, 页面内容见标题二@auth.route('/confirm')@login_requireddef resend_confirmation():  #重新发送确认邮件    token = current_user.generate_token()    send_mail(current_user.email, 'Confirm your account', 'auth/email/confirm', user=current_user, token=token)    flash('a confirm email has been sent to your email.')    return redirect(url_for('main.index'))

代码说明:

    第二章我们讲过请求钩子, before_request注册一个函数, 在所有请求之前运行, auth蓝本注册的请求钩子的作用域只在该蓝本定义的路由中有效, 如果想把作用域应用的程序全局, 就要使用before_app_request。

    这样before_request函数就会在所有请求之前运行, 该函数的作用是使未认证用户登录以后重定向到未认证提醒页面,所以要加上current_user.is_authenticated() 和not current_user.confirm这两个判断条件,。

    然后程序就会重定向到auth.unconfirmed, 可是浏览器在发送auth.unconfirmed请求以后, 还是会先运行before_request函数, 就会再次重定向, 陷入循环, 因此我们加上request.endpoint[:5] != 'auth.'(endpoint存储的是请求端点, 如主页的请求断点就是main.index,)这个条件,这样访问auth蓝本的路由就不会重定向了。

    auth.unconfirmed路由返回提醒页面, 提醒页面包括一链接, 指向auth.resend_confirmation, 重新发送认证邮件。

    点击链接后, 程序重新发送验证邮件, 用户登录邮箱进行确认即可。

二. 修改|-app/templates/auth/unconfirmed.html

{% extends 'base.html' %}{% block title %}Flasky - Confirm your account{% endblock %}{% block page_content %}

三. 效果演示与代码说明

本次用登录sherry用户的过程来讲解程序的执行过程:

可见sherry用户未进行验证, 我们用浏览器访问程序主页,before_app_request注册的函数会在每个请求之前运行, 但是里面的限制条件只有已登录的未验证用户才会重定向, 所以未登录之前我们不用考虑这个钩子, 程序直接显示主页, 点击右上角登录链接显示登录页面:

输入信息并点击提交按钮以后, 我们就要考虑钩子的作用了, 见处理登陆的视图函数:

@auth.route('/login', methods=['GET', 'POST'])def login():    form = LoginForm()    if form.validate_on_submit():        user = User.query.filter_by(email=form.email.data).first()        if user and user.verify_password(form.password.data):            login_user(user, form.remember_me)            return redirect(request.args.get('next') or url_for('main.index'))        flash('Invalid username or password.')    return render_template('auth/login.html', form=form)

  我们点击提交按钮以后执行if语句块, 经过密码验证以后代码会登录用户, 并且返回主页的重定向, 浏览器发出请求主页的url后, 先执行钩子函数, 此时用户已登录, 并且未验证, 访问的又不是端点又不是auth., 于是重定向到auth.unconfirmed; 

  浏览器再发出请求auth.unconfirmed的url, 因为钩子函数中的条件request.endpoint[:5] != 'auth.', 所以所有对auth蓝本定义的路由的请求都可以忽略钩子函数, 返回auth/unconfirmed.html提醒页面:

点击链接, 访问auth.resend_confirmation视图函数, 重新发送邮件;

发完之后提示flash消息, 并且重定向到主页, 因为钩子函数的原因, 重定向到auth.unconfirmed:

我们登录邮箱, 发现一封新邮件:

打开后:

发现验证链接, 点击链接, 访问auth.confirm视图函数, 进行用户的认证, 认证通过, 用户的confirm属性值变为1:

重定向到主页, 因为此时用户已经认证, 所以可以忽略钩子函数, 程序返回主页:

*演示过程的说明都是按照代码的执行顺序讲解的。

四. request.endpoint != 'static'

注释:钩子函数中的request.endpoint != 'static'表明, 请求的端点是static, 可以忽略钩子函数:

可能有人会问, 我们的路由都是由auth和main蓝本定义的, 哪有名为static的端点?

还记得第二章的url_map吗:

最后一个端点就是static, 举例来说, 我们访问127.0.0.1:5000/static/favicon.ico就会得到我们的静态文件favicon.ico。

你可能感兴趣的文章
新一代Java模板引擎Thymeleaf
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
Spring Boot构建简单的微博应用
查看>>
Spring处理表单提交
查看>>
Spring MVC异常处理
查看>>
Leetcode 1180. Count Substrings with Only One Distinct Letter [Python]
查看>>
PHP 7 的五大新特性
查看>>
php使用 memcache 来存储 session
查看>>
php实现socket(转)
查看>>
PHP底层的运行机制与原理
查看>>
深入了解php底层机制
查看>>
PHP中的stdClass 【转】
查看>>
XHProf-php轻量级的性能分析工具
查看>>
PHP7新特性 What will be in PHP 7/PHPNG
查看>>
比较strtr, str_replace和preg_replace三个函数的效率
查看>>
ubuntu 下编译PHP5.5.7问题:configure: error: freetype.h not found.
查看>>
PHP编译configure时常见错误 debian centos
查看>>
configure: error: Please reinstall the BZip2 distribution
查看>>
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
【增强学习在无人驾驶中的应用】
查看>>